package jmine.tec.hydra.dao;

import java.util.List;

import jmine.tec.hydra.domain.HydraSystem;
import jmine.tec.hydra.domain.specification.HydraSpecificationImpl;

import org.hibernate.Criteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import bancosys.tec.persist.dao.BaseDAO;
import bancosys.tec.persist.dao.BeanNotFoundException;
import bancosys.tec.persist.hibernate.RestrictionsUtils;

/**
 * @author piercio
 */
public class HydraSpecificationDAO extends BaseDAO<HydraSpecificationImpl> {

    /**
     * Retorna todas as especificações (habilitadas ou não) para uma dada ação.
     * 
     * @param action a ação de integração.
     * @return todas as especificação para uma dada ação.
     * @deprecated esse método não deveria ser de utilidade, pois busca especificações sem conhecimento de sistema.
     */
    @Deprecated
    public List<HydraSpecificationImpl> findAllByAction(String action) {
        Criteria crit = this.createCriteria();
        crit.add(Restrictions.eq("action", action));
        return this.executeQuery(crit);
    }

    /**
     * Devolve a especificação para um dado sistema e uma dada ação.
     * 
     * @param action a ação.
     * @param system o sistema.
     * @return a especificação.
     * @throws BeanNotFoundException caso não encontre nenhuma.
     */
    public HydraSpecificationImpl findByActionSystem(HydraSystem system, String action) throws BeanNotFoundException {
        Criteria crit = this.createCriteria();
        crit.add(Restrictions.eq("action", action));
        crit.add(Restrictions.eq("system", system));
        return this.executeSingleQuery(crit);
    }

    /**
     * Retorna uma lista de {@link HydraSpecificationImpl} através de um {@link HydraSystem} e uma ação, sendo ela inteira ou só uma parte
     * dela.
     * 
     * @param system {@link HydraSystem}.
     * @param action ação, ou parte da ação.
     * @return uma lista de {@link HydraSpecificationImpl} através de um {@link HydraSystem} e uma ação, sendo ela inteira ou só uma parte
     * dela.
     */
    public List<HydraSpecificationImpl> findBySystemActionLike(HydraSystem system, String action) {
        Criteria criteria = this.createCriteria();
        RestrictionsUtils.addRestrictionEqId(criteria, "system.id", system);
        if (action != null && !action.trim().equals("")) {
            criteria.add(Restrictions.ilike("action", action, MatchMode.ANYWHERE));
        }
        return this.executeQuery(criteria);
    }

    /**
     * Busca todas as especificações por sistema.
     * 
     * @param system sistema.
     * @return lista de especificações associadas ao sistema informado.
     */
    public List<HydraSpecificationImpl> findBySystem(HydraSystem system) {
        Criteria crit = this.createCriteria();
        crit.add(Restrictions.eq("system", system));
        crit.addOrder(Order.asc("id"));
        return this.executeQuery(crit);
    }
}
